﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Fiuba.Algo3.Titiritero;
using System.Drawing;
using System.IO;
using System.Xml;
namespace BattleCity
{
    public delegate void DelegadoMision(string nombre);
    class BattleCityJuego
    {
        private ISuperficieDeDibujo superficieDeDibujo;
        private ControladorJuego controladorJuego = null;
        private List<String> misiones;
        public Mision mision;
        List<IDibujable> dibujables = new List<IDibujable>();
        
        public event DelegadoMision NuevaMision;
        private void nada(string nombre) { }

        public BattleCityJuego(ISuperficieDeDibujo superficieDeDibujo)
        {

            //Busca Archivos Xml con Misiones carga los paths en una lista
            misiones = Examinar.recursivoDir(@"Misiones\");
            //Esta superficie es el Objeto que se ve en el form
            this.superficieDeDibujo = superficieDeDibujo;
            NuevaMision += new DelegadoMision(nada);
            Marcador.Reset();

            Escenario.getEscenario().Objetos.ObjetoAdd += new DelegadoObjetos(ObjetoAgregado);
            Escenario.getEscenario().Objetos.ObjetoDel += new DelegadoObjetos(ObjetoEliminado);
            Escenario.getEscenario().Objetos.ObjetosClear += new DelegadoClear(TodosLosObjetosBorrados);
        }

        //Inicia la mision siguiente instanciando la mision y seteando el controlador
        public void Comenzar()
        {

            //Si la lista misiones ya no tiene archivos, da por Ganado el juego
            if (misiones.Count == 0)
            {
                Gano();
            }
            else
            {
                //toma un archivo de una lista y se lo pasa a Mision Por Parametro para que lo lea, y arme la mision
                String ArchivoConfiguracionDeMision = misiones.First();
                misiones.Remove(ArchivoConfiguracionDeMision);

                mision = new Mision(ArchivoConfiguracionDeMision);
                NuevaMision(mision.nombre);
                CargarControlador(mision);
            }
        }

        //setea el controlador a partir de una mision ya cargada
        private void CargarControlador(Mision mision)
        {
            // si cargamos un controlador ya habiendo un controlador creado(ejemplo, al iniciar la segunda mision)
            // quedan los dos controladores ciclando a la vez, entonces primero tenemos que matar el anterior
            if (this.controladorJuego != null)
            {
                Detener();
                controladorJuego = null;
            }

            //seteamos el controlador:
            this.controladorJuego = new ControladorJuego(superficieDeDibujo, new Bitmap(@"Images\Back.jpg"));
            this.controladorJuego.IntervaloSimulacion = 20;

            this.controladorJuego.Vivieron += new Controlador(ifObjetosViven);

            Base.getBase().BaseDestruida += new DelegadoBase(Perdio);
            TanqueUser.getTanqueUser().UserDestruido += new DelegadoUser(Perdio);
            Flota.getFlota().FlotaDestruida += new DelegadoFlota(Comenzar);

            this.controladorJuego.setObjetosVivos(Escenario.getEscenario().Objetos.Items);
            this.controladorJuego.setDibujables(dibujables);
            this.controladorJuego.Presentacion = mision.Presentacion;

            //inicia el juego

            this.controladorJuego.ComenzarJuego();
        }
        private void ifObjetosViven()
        {
            if (todosBorrados == true)
            {
                todosBorrados = false;
            }
            else
            {
                if (IVivosEliminadosAuxiliar.Count > 0)
                {
                    int i = 0;
                    while (i < dibujables.Count)
                    {
                        foreach (IObjetoVivo ob in IVivosEliminadosAuxiliar)
                        {
                            if (dibujables[i].Posicionable == (IPosicionable)ob)
                            {
                                dibujables.RemoveAt(i);
                            }
                        }
                        i++;
                    }
                    IVivosEliminadosAuxiliar = new List<IObjetoVivo>();
                }
                if (IVivosAgregadosAuxiliar.Count > 0)
                {
                    dibujables.AddRange(VistasFactory.Get(IVivosAgregadosAuxiliar));
                    IVivosAgregadosAuxiliar = new List<IObjetoVivo>();
                }
                
            }
            this.controladorJuego.setDibujables(dibujables);
        }
        List<IObjetoVivo> IVivosAgregadosAuxiliar = new List<IObjetoVivo>();
        List<IObjetoVivo> IVivosEliminadosAuxiliar = new List<IObjetoVivo>();
        bool todosBorrados = false;
        private void ObjetoAgregado(IObjetoVivo objeto)
        {
            IVivosAgregadosAuxiliar.Add(objeto);
        }
        private void ObjetoEliminado(IObjetoVivo objeto)
        {
            if ( IVivosAgregadosAuxiliar.Contains(objeto))
            {
                IVivosAgregadosAuxiliar.Remove(objeto);
            }
            else
            {
                IVivosEliminadosAuxiliar.Add(objeto);
            }
        }
        private void TodosLosObjetosBorrados()
        {
            this.dibujables = new List<IDibujable>();
            IVivosAgregadosAuxiliar = new List<IObjetoVivo>();
            IVivosEliminadosAuxiliar = new List<IObjetoVivo>();
            todosBorrados = true;
        }



        public void Detener()
        {
            if (controladorJuego != null)
                this.controladorJuego.DetenerJuego();
        }
        public void Continuar()
        {
            if (controladorJuego != null)
                this.controladorJuego.ComenzarJuego();
        }
        //cuando el user muere, la base muere o los enemigos mueren, lanzan eventos 
        //si la base o el user muere, cae aca, dando por perdido el juego:
        private void Perdio()
        {
            Detener();
            this.controladorJuego.MostrarImagen(new VistaDerrota(@"Images\Derrota.jpg"), 120);
        }
        private void Gano()
        {
            Detener();
            this.controladorJuego.MostrarImagen(new VistaDerrota(@"Images\Victoria.jpg"), 120);
        }
        //Si los enemigos mueren, va a Comenzar() para ir a la siguiente mision

        public void Guardar()
        {
            mision.GuardarEstadoActual(@"Objetos\Objetos.xml");
        }

        public void ReanudarUltimaPartida()
        {
            String ArchivoConfiguracion = @"Objetos\Objetos.xml";

            mision = new Mision(ArchivoConfiguracion);
            while (mision.pathArchivoConfiguracionDeMision != misiones[0])
            {
                misiones.Remove(misiones[0]);
            }
            misiones.Remove(mision.pathArchivoConfiguracionDeMision);

            CargarControlador(mision);

        }

    }       
}
